summaryrefslogtreecommitdiffstats
path: root/src/hid_core/resources/abstracted_pad/abstract_pad.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/hid_core/resources/abstracted_pad/abstract_pad.cpp')
-rw-r--r--src/hid_core/resources/abstracted_pad/abstract_pad.cpp294
1 files changed, 294 insertions, 0 deletions
diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp
new file mode 100644
index 000000000..2c7691d7c
--- /dev/null
+++ b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp
@@ -0,0 +1,294 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "hid_core/hid_result.h"
+#include "hid_core/resources/abstracted_pad/abstract_pad.h"
+#include "hid_core/resources/applet_resource.h"
+#include "hid_core/resources/npad/npad_types.h"
+
+namespace Service::HID {
+
+AbstractPad::AbstractPad() {}
+
+AbstractPad::~AbstractPad() = default;
+
+void AbstractPad::SetExternals(AppletResourceHolder* applet_resource,
+ CaptureButtonResource* capture_button_resource,
+ HomeButtonResource* home_button_resource,
+ SixAxisResource* sixaxis_resource, PalmaResource* palma_resource,
+ VibrationHandler* vibration) {
+ applet_resource_holder = applet_resource;
+
+ properties_handler.SetAppletResource(applet_resource_holder);
+ properties_handler.SetAbstractPadHolder(&abstract_pad_holder);
+
+ led_handler.SetAppletResource(applet_resource_holder);
+ led_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ led_handler.SetPropertiesHandler(&properties_handler);
+
+ ir_sensor_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ ir_sensor_handler.SetPropertiesHandler(&properties_handler);
+
+ nfc_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ nfc_handler.SetPropertiesHandler(&properties_handler);
+
+ mcu_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ mcu_handler.SetPropertiesHandler(&properties_handler);
+
+ std::array<NpadVibrationDevice*, 2> vibration_devices{&vibration_left, &vibration_right};
+ vibration_handler.SetAppletResource(applet_resource_holder);
+ vibration_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ vibration_handler.SetPropertiesHandler(&properties_handler);
+ vibration_handler.SetN64Vibration(&vibration_n64);
+ vibration_handler.SetVibration(vibration_devices);
+ vibration_handler.SetGcVibration(&vibration_gc);
+
+ sixaxis_handler.SetAppletResource(applet_resource_holder);
+ sixaxis_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ sixaxis_handler.SetPropertiesHandler(&properties_handler);
+ sixaxis_handler.SetSixaxisResource(sixaxis_resource);
+
+ button_handler.SetAppletResource(applet_resource_holder);
+ button_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ button_handler.SetPropertiesHandler(&properties_handler);
+
+ battery_handler.SetAppletResource(applet_resource_holder);
+ battery_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ battery_handler.SetPropertiesHandler(&properties_handler);
+
+ palma_handler.SetAbstractPadHolder(&abstract_pad_holder);
+ palma_handler.SetPropertiesHandler(&properties_handler);
+ palma_handler.SetPalmaResource(palma_resource);
+}
+
+void AbstractPad::SetNpadId(Core::HID::NpadIdType npad_id) {
+ properties_handler.SetNpadId(npad_id);
+}
+
+Result AbstractPad::Activate() {
+ if (ref_counter == std::numeric_limits<s32>::max() - 1) {
+ return ResultNpadHandlerOverflow;
+ }
+
+ if (ref_counter != 0) {
+ ref_counter++;
+ return ResultSuccess;
+ }
+
+ std::size_t stage = 0;
+ Result result = ResultSuccess;
+
+ if (result.IsSuccess()) {
+ stage++;
+ result = properties_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = led_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = ir_sensor_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = mcu_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = nfc_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = vibration_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = sixaxis_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = button_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = battery_handler.IncrementRefCounter();
+ }
+ if (result.IsSuccess()) {
+ stage++;
+ result = palma_handler.IncrementRefCounter();
+ }
+
+ if (result.IsSuccess()) {
+ ref_counter++;
+ return result;
+ }
+
+ if (stage > 9) {
+ battery_handler.DecrementRefCounter();
+ }
+ if (stage > 8) {
+ button_handler.DecrementRefCounter();
+ }
+ if (stage > 7) {
+ sixaxis_handler.DecrementRefCounter();
+ }
+ if (stage > 6) {
+ vibration_handler.DecrementRefCounter();
+ }
+ if (stage > 5) {
+ nfc_handler.DecrementRefCounter();
+ }
+ if (stage > 4) {
+ mcu_handler.DecrementRefCounter();
+ }
+ if (stage > 3) {
+ ir_sensor_handler.DecrementRefCounter();
+ }
+ if (stage > 2) {
+ led_handler.DecrementRefCounter();
+ }
+ if (stage > 1) {
+ properties_handler.DecrementRefCounter();
+ }
+ return result;
+}
+
+Result AbstractPad::Deactivate() {
+ if (ref_counter == 0) {
+ return ResultNpadResourceNotInitialized;
+ }
+
+ ref_counter--;
+ battery_handler.DecrementRefCounter();
+ button_handler.DecrementRefCounter();
+ sixaxis_handler.DecrementRefCounter();
+ vibration_handler.DecrementRefCounter();
+ nfc_handler.DecrementRefCounter();
+ ir_sensor_handler.DecrementRefCounter();
+ mcu_handler.DecrementRefCounter();
+ led_handler.DecrementRefCounter();
+ properties_handler.DecrementRefCounter();
+ palma_handler.DecrementRefCounter();
+
+ return ResultSuccess;
+}
+
+Result AbstractPad::ActivateNpad(u64 aruid) {
+ Result result = ResultSuccess;
+ if (result.IsSuccess()) {
+ result = properties_handler.ActivateNpadUnknown0x88(aruid);
+ }
+ if (result.IsSuccess()) {
+ result = sixaxis_handler.UpdateSixAxisState2(aruid);
+ }
+ if (result.IsSuccess()) {
+ result = battery_handler.UpdateBatteryState(aruid);
+ }
+ return result;
+}
+
+NpadAbstractedPadHolder* AbstractPad::GetAbstractedPadHolder() {
+ return &abstract_pad_holder;
+}
+
+NpadAbstractPropertiesHandler* AbstractPad::GetAbstractPropertiesHandler() {
+ return &properties_handler;
+}
+
+NpadAbstractLedHandler* AbstractPad::GetAbstractLedHandler() {
+ return &led_handler;
+}
+
+NpadAbstractIrSensorHandler* AbstractPad::GetAbstractIrSensorHandler() {
+ return &ir_sensor_handler;
+}
+
+NpadAbstractMcuHandler* AbstractPad::GetAbstractMcuHandler() {
+ return &mcu_handler;
+}
+
+NpadAbstractNfcHandler* AbstractPad::GetAbstractNfcHandler() {
+ return &nfc_handler;
+}
+
+NpadAbstractVibrationHandler* AbstractPad::GetAbstractVibrationHandler() {
+ return &vibration_handler;
+}
+
+NpadAbstractSixAxisHandler* AbstractPad::GetAbstractSixAxisHandler() {
+ return &sixaxis_handler;
+}
+
+NpadAbstractButtonHandler* AbstractPad::GetAbstractButtonHandler() {
+ return &button_handler;
+}
+
+NpadAbstractBatteryHandler* AbstractPad::GetAbstractBatteryHandler() {
+ return &battery_handler;
+}
+
+NpadN64VibrationDevice* AbstractPad::GetN64VibrationDevice() {
+ return &vibration_n64;
+}
+
+NpadVibrationDevice* AbstractPad::GetVibrationDevice(Core::HID::DeviceIndex device_index) {
+ if (device_index == Core::HID::DeviceIndex::Right) {
+ return &vibration_right;
+ }
+ return &vibration_left;
+}
+
+void AbstractPad::GetLeftRightVibrationDevice(std::vector<NpadVibrationDevice*> list) {
+ list.emplace_back(&vibration_left);
+ list.emplace_back(&vibration_right);
+}
+
+NpadGcVibrationDevice* AbstractPad::GetGCVibrationDevice() {
+ return &vibration_gc;
+}
+
+Core::HID::NpadIdType AbstractPad::GetLastActiveNpad() {
+ return properties_handler.GetNpadId();
+}
+
+void AbstractPad::UpdateInterfaceType() {
+ if (interface_type != properties_handler.GetInterfaceType()) {
+ Update();
+ }
+ battery_handler.UpdateBatteryState();
+}
+
+void AbstractPad::Update() {
+ properties_handler.UpdateDeviceType();
+ led_handler.SetNpadLedHandlerLedPattern();
+ vibration_handler.UpdateVibrationState();
+ sixaxis_handler.UpdateSixAxisState();
+ nfc_handler.UpdateNfcState();
+ ir_sensor_handler.UpdateIrSensorState();
+ mcu_handler.UpdateMcuState();
+ palma_handler.UpdatePalmaState();
+ battery_handler.UpdateBatteryState();
+ button_handler.EnableCenterClamp();
+
+ interface_type = properties_handler.GetInterfaceType();
+
+ std::scoped_lock lock{*applet_resource_holder->shared_mutex};
+ properties_handler.UpdateAllDeviceProperties();
+ battery_handler.UpdateCoreBatteryState();
+ button_handler.UpdateCoreBatteryState();
+}
+
+void AbstractPad::UpdatePadState() {
+ button_handler.UpdateAllButtonLifo();
+ sixaxis_handler.UpdateSixAxisState();
+ battery_handler.UpdateCoreBatteryState();
+}
+
+void AbstractPad::EnableAppletToGetInput(u64 aruid) {
+ button_handler.UpdateButtonState(aruid);
+ sixaxis_handler.UpdateSixAxisState(aruid);
+ battery_handler.UpdateBatteryState(aruid);
+}
+
+} // namespace Service::HID